package thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @author Duanyu
 * @date 2021-11-18 20:14
 */
public class BlockingQueueTest {



    public static void main(String[] args) {
        /**
         * BlockingQueue常用实现类：
         *  ArrayBlockingQueue：基于数组的阻塞队列实现，在ArrayBlockingQueue内部维护了一个初始化给定长度数组
         *  LinkedBlockingQueue：基于链表的阻塞队列，它能够高效的处理并发数据，因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步，
         *      这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据，以此来提高整个队列的并发性能，同时我们还需要注意初始化时一定要指定长度，
         *      否则它默认为Integer.MAX_VALUE，这样一旦生产速度高于消费速度，系统内存直接就消耗殆尽了。
         *
         *  DelayQueue：它里面的元素只有当其指定的延迟时间到了，才能够从队列中获取到该元素。
         *      DelayQueue是一个没有大小限制的队列，因此往队列中插入数据的操作（生产者）永远不会被阻塞，而只有获取数据的操作（消费者）才会被阻塞。
         *      常见的例子比如使用一个DelayQueue来管理一个超时未响应的连接队列。
         *
         *  PriorityBlockingQueue：基于优先级的阻塞队列（优先级的判断通过构造函数传入的Compator对象来决定），但需要注意的是PriorityBlockingQueue并不会阻塞数据生产者，
         *      而只会在没有可消费的元素时阻塞消费者。因此使用的时候要特别注意，生产者生产数据的速度绝对不能快于消费者消费数据的速度，否则时间一长，会最终耗尽所有的可用堆内存空间。
         *      在实现PriorityBlockingQueue时，内部控制线程同步的锁采用的是公平锁。
         *
         *  SynchronousQueue:一种无缓冲的等待队列,没有中间商，生产者直接对接消费者，如果一方没有找到合适的目标，那么大家都要等待。
         *
         *
         */

        /**
         * BlockingQueue核心方法：
         *  offer(E e)：将e加到队列中，如果队列还有位置,添加成功返回true，已满则失败返回false.
         *  offer(E e,long timeout, TimeUnit unit):可以设定等待时间，如果在指定的时间内还不能往队列中添加，则返回false
         *
         *  put(E e):将e加到队列中，如果队列已满则一直阻塞直到队列有位置再添加
         *  take():取出队列排在首位的元素,若队列为空，则一直阻塞直到队列中有元素再取出
         *
         *  poll():取出队列排在首位的元素,如果队列为空返回null
         *  poll(long time,TimeUnit unit):取出队列排在首位的元素，若不能立即取出则等待time规定的时间，若还没取到则返回null
         *
         *  drainTo(Collection<? super E> coll, int num)：一次从队列中获取所有可用的元素，也可以指定个数
         */
        BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);

        System.out.println(queue.offer("AAD"));
        System.out.println(queue.offer("Da"));
        System.out.println(queue.offer("AA"));
        System.out.println(queue.offer("AA"));

        //String poll = queue.drainTo();


        System.out.println(queue.element());
    }
}
